/*********************************************************
 * copyright xinbohit.com 版权所有 
 * 开发人员：IvanYu
 * 创建时间：2014/6/12 0:50:08
 * 描述说明：
 * 
 * 更改历史：
 * 
 * *******************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using KouSuan.Models;
using KouSuan.Exceptions;

namespace KouSuan.Generaters
{
    static class CommonMethords
    {
        static Random r;
        static CommonMethords()
        {
            r = new Random();
        }

        /// <summary>
        /// 一般加法算式生成算法，指定和值范围生成算式，不考虑进位与否
        /// </summary>
        /// <param name="sum">和值范围</param>
        /// <returns></returns>
        public static ExpressionModel CommonAdditionGenerate(int sum)
        {
            ExpressionModel em = new ExpressionModel();

            // 取随机值时范围应上浮1
            int point = sum + 1;
            int num1 = r.Next(point);
            int num2 = 0;
            if (num1 != sum)
            {
                num2 = r.Next(point - num1);
            }
            em.LeftNum = num1;
            em.RightNum = num2;
            em.Oprator = '+';

            return em;
        }

        /// <summary>
        /// 一般减法生成算法，指定和值范围上 临界点，不考虑是否退位
        /// </summary>
        /// <param name="sum">和值范围上临界点</param>
        /// <returns></returns>
        public static ExpressionModel CommonSubstractionGenerate(int sum)
        {
            ExpressionModel em = new ExpressionModel();

            // 取随机值时范围应上浮1
            int point = sum + 1;
            int num1 = r.Next(point);
            int num2 = 0;

            if (num1 == 0)
            {
                num2 = r.Next(point);
            }
            else if (num1 == 1)
            {
                num2 = r.Next(sum - 1) + 2;
            }
            else if (num1 == sum)
            {
                num2 = r.Next(sum);
            }
            else
            {
                int i = r.Next(2);
                if (i == 0)
                {
                    num2 = r.Next(1, point - num1) + num1;
                }
                else
                {
                    num2 = r.Next(num1 + 1);
                }
            }

            em.LeftNum = Math.Max(num1, num2);
            em.RightNum = Math.Min(num1, num2);
            em.Oprator = '-';

            return em;
        }

        /// <summary>
        /// 进位加法
        /// </summary>
        /// <param name="sum"></param>
        /// <returns></returns>
        public static ExpressionModel CarrySaveAdditionGenerate(int sum)
        {
            if (sum < 10)
            {
                throw new GenerateExpressionException("和小于10无法生成进位加法。");
            }

            int shiwei = sum / 10;

            ExpressionModel em = new ExpressionModel();

            int num1Shiwei = r.Next(shiwei - 1);
            int num1Gewei = r.Next(9) + 1;
            int num1 = num1Shiwei * 10 + num1Gewei;

            //int num2Shiwei = r.Next((int)Math.Pow(10, sum.ToString().Length - 1) - num1Shiwei - 1);
            int num2Shiwei = r.Next(shiwei-num1Shiwei);
            int num2Gewei = r.Next(num1Gewei) + 10 - num1Gewei;
            int num2 = num2Shiwei * 10 + num2Gewei;

            em.LeftNum = num1;
            em.RightNum = num2;
            em.Oprator = '+';

            return em;
        }

        /// <summary>
        /// 借位减法生成
        /// </summary>
        /// <param name="sum"></param>
        /// <returns></returns>
        public static ExpressionModel AbdicationSubtractionGenerate(int sum)
        {
            if (sum < 10)
            {
                throw new GenerateExpressionException("和小于10无法生成借位减法");
            }

            int shiwei = sum / 10;
            ExpressionModel em = new ExpressionModel();

            int num1Shiwei = r.Next(shiwei) + 1;
            int num1Gewei = 0;
            if (num1Shiwei != 10)
            {
                num1Gewei = r.Next(9);
            }
            int num1 = num1Shiwei * 10 + num1Gewei;

            int num2Shiwei = r.Next(num1Shiwei);
            int num2Gewei = r.Next(9 - num1Gewei) + num1Gewei + 1;
            int num2 = num2Shiwei * 10 + num2Gewei;

            em.LeftNum = num1;
            em.RightNum = num2;
            em.Oprator = '-';

            return em;
        }
    }
}
